struct BilibiliInfo {
    rid: String,
    client: reqwest::Client,
}

impl BilibiliInfo {
    fn new() -> BilibiliInfo {
        return BilibiliInfo {
            rid: String::from(""),
            client: reqwest::ClientBuilder::new().build().unwrap(),
        };
    }

    async fn get_real_rid(&mut self, room_id: &str) {
        let url = format!(
            "https://api.live.bilibili.com/room/v1/Room/room_init?id={}",
            &room_id
        );
        let resp: serde_json::Value = self
            .client
            .get(url)
            .send()
            .await
            .expect("Failed to send bili info req")
            .json()
            .await
            .unwrap();
        if resp["code"].as_i64() != Some(0) {
            println!("Error resp code failed");
            return;
        }
        if resp["data"]["live_status"].as_i64() != Some(1) {
            println!("Error not live");
            return;
        }
        self.rid = resp["data"]["room_id"].as_i64().unwrap().to_string();
    }

    async fn get_play_url(&self, pf: &str) {
        let url = format!("https://api.live.bilibili.com/xlive/web-room/v1/playUrl/playUrl");
        let params = [
            ("cid", self.rid.as_str()),
            ("qn", "10000"),
            ("platform", pf),
            ("https_url_req", "1"),
            ("ptype", "16"),
        ];
        let resp: serde_json::Value = self
            .client
            .get(url)
            .query(&params)
            .send()
            .await
            .expect("Error")
            .json()
            .await
            .unwrap();

        let durl_value_arr = resp["data"]["durl"].as_array().unwrap();
        for url_value_item in durl_value_arr {
            println!("url: [{}]", url_value_item["url"].as_str().unwrap());
        }
    }
}

pub async fn get_bilibili_real_url(room_id: &str) {
    let mut info = BilibiliInfo::new();
    info.get_real_rid(&room_id).await;
    info.get_play_url("web").await;
}
